#include "userinterface.h"
#include "ui_userinterface.h"
#include "audioinput.h"

#include "audiooutput.h"
// 用户界面的代码

Userinterface::Userinterface(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Userinterface)
{
    ui->setupUi(this);
    this->setAcceptDrops(1);
    abs = new Abs(this);
    QObject::connect(abs,&Abs::sndImage,this,&Userinterface::recvImage);
    thread = new myThread(this);
    QObject::connect(thread,&myThread::sndDesk,this,&Userinterface::recvDesk);
    QObject::connect(thread,&myThread::threadstopped,ui->label_2,&QLabel::clear);
    QFile file(":/interface.qss");
    if(file.open(QFile::OpenModeFlag::ReadOnly)){
        this->setStyleSheet(file.readAll());
    }
    audioInput= new AudioInput(this);
    audioOutput = new AudioOutput(this);

    QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
    QObject::connect(audioInput,&AudioInput::sndVoice,this,&Userinterface::handleAudioData);
      QAudioFormat format = audioInput->input->format();
      if (!info.isFormatSupported(format)) {
          qWarning() << "当前音频格式不支持，使用最接近的格式";
          // 这里我们无法更改AudioInput的格式，因为它没有提供setFormat方法
          // 可以考虑在AudioInput类中添加setFormat方法来解决这个问题
      }

}

Userinterface::~Userinterface()
{



    delete ui;
}

void Userinterface::setLoginInterface(QWidget *w)
{
    loginInterface = w;
}

void Userinterface::setClient(QTcpSocket *client)
{
    this->client = client;
}
void Userinterface::setCamerPic(QPixmap &pic)
{

    pic = pic.scaled(ui->label->size());
    ui->label->setPixmap(pic);
}
void Userinterface::setDeskPic(QPixmap &pic)
{

    pic = pic.scaled(ui->label_2->size());
    ui->label_2->setPixmap(pic);
}
// 返回登录界面
void Userinterface::on_pushButton_clicked()
{

    this->hide();
    // === 新增：发送下线包 ===
    if (client && client->state() == QTcpSocket::ConnectedState) {
        Pack offlinePack;
        offlinePack.setType(TYPE_USER_OFFLINE);
        // 获取当前登录用户名（需从Widget传递或保存到Userinterface中）
        // 假设Userinterface有currentUsername成员变量，登录时从Widget传入
        offlinePack << currentUsername;
        offlinePack >> client;
    }

    this->client->disconnectFromHost();
    loginInterface->show();
}

void Userinterface::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
}

void Userinterface::dropEvent(QDropEvent *event)
{
    QString filepath = event->mimeData()->urls()[0].toLocalFile();
    QString filename = filepath.split("/").last();
    qDebug() << filename;

    Pack p1,p2,p3;
    p1.setType(TYPE_FILE_UPLOAD_REQUEST);
    p2.setType(TYPE_FILE_UPLOADING);
    p3.setType(TYPE_FILE_UPLOAD_END);

    file.setFileName(filepath);
    file.open(QFile::ReadOnly);


    // ① 将文件名发给服务器
    p1 << filename;
    p1 >> client;

    // ② 将文件内容发给服务器
    while(1){
        QByteArray arr = file.read(4096);// 读取文件中4096字节的数据,存入arr里面
        if(arr.isEmpty()){break;}
        // 将 arr 放到协议包中发给服务器
        p2.append(arr.data(),arr.size());// 将arr中的数据，存入协议包p2
        p2 >> client;// p2发送给服务器
    }

    // ③ 发送一个结束通知给服务器，通知服务器文件传输完成

    p3 >> client;
    file.close();
}

void Userinterface::on_pushButton_2_clicked()
{
    QString filepath = QFileDialog::getOpenFileName(this,"上传文件","D:/");
    QString filename = filepath.split("/").last();
    qDebug() << filename;

    Pack p1,p2,p3;
    p1.setType(TYPE_FILE_UPLOAD_REQUEST);
    p2.setType(TYPE_FILE_UPLOADING);
    p3.setType(TYPE_FILE_UPLOAD_END);

    file.setFileName(filepath);
    file.open(QFile::ReadOnly);
    p1 << filename;
    p1 >> client;


    while(1){
        QByteArray arr = file.read(4096);// 读取文件中4096字节的数据,存入arr里面
        if(arr.isEmpty()){break;}
        // 将 arr 放到协议包中发给服务器
        p2.append(arr.toStdString().data(),arr.size());// 将arr中的数据，存入协议包p2
        p2 >> client;// p2发送给服务器
    }
    p3 >> client;
    file.close();
}

void Userinterface::recvImage(QImage &image)
{
    // 现在，参数image就是摄像头拍摄到的画面
    QImage lb_image = image.scaled(ui->label->size());// 将摄像头拍摄到的画面，大小适应成label的大小

    QPixmap pic = QPixmap::fromImage(lb_image);// 将lb_image 转换成 QPixmap 类型，因为label里面，只能显示QPximap类型的图片
    ui->label->setPixmap(pic);// 将 pic 设置到 label上去


// 画面就在这发送了，画面发送的逻辑：将图片转换成字节流，写入协议包，通过协议包进行发送
// 结论就是：将QImage 转换成 QByteArray
    QByteArray arr;// 创建一个字节流对象
    QBuffer buf(&arr); // 以 arr指向的地址为缓存区，创建buf，如果向buf中写入内容，相当于向arr中写入内容
    lb_image.save(&buf,"jpg",60/*最后一个参数为图片的转换质量，根据实际情况自己调节*/); // 将 图片 lb_image 保存到buf里面去。
    // 到此为止，图片的所有内容就转换成字节流保存到 arr里面了

    Pack pack;
    int image_size = arr.size(); // 图片总大小
    //qDebug() << image_size;
    int writed_size = 0;// 记录一帧已发送多少字节，方便计算什么时候发送了最后一包图片

    while(1){
        if(writed_size + 4096 >= image_size){
            // 如果在当前已发送图片字节数的基础上，再发送4096字节，超出图片总大小，说明本次发送是一帧图片的最后一包

            // 将图片 arr 存入协议包
            pack.setType(TYPE_SEND_CAMERA_END);
            pack.append(arr.data()+writed_size,image_size - writed_size);
            pack >> client;
            break;
        }else{
            // 一帧图片的前面几包
            pack.setType(TYPE_SENDING_CAMERA);
            pack.append(arr.data()+writed_size,4096);
            pack >> client;
        }
        writed_size += 4096;
    }
}

void Userinterface::recvDesk(QPixmap pic)
{
    pic = pic.scaled(ui->label_2->size());
    ui->label_2->setPixmap(pic);

    QByteArray arr;
    QBuffer buf(&arr);
    pic.save(&buf,"jpg",30);

    Pack pack;
    int image_size=arr.size();

    int writed_size=0;
    while(1){
        if(writed_size+4096>=image_size){
            pack.setType(TYPE_SEND_DESKTOP_END);
            pack.append(arr.data()+writed_size,image_size-writed_size);
            pack>>client;
            break;
        }else{
            pack.setType(TYPE_SENDING_DESKTOP);
            pack.append(arr.data()+writed_size,4096);
            pack >> client;
        }
        writed_size+=4096;
    }
}

void Userinterface::onMessageWindowClosed()
{
    msg = nullptr; // 窗口销毁后，指针重置为nullptr
}

void Userinterface::on_pushButton_3_clicked()
{
    if(num)
    {
    abs->camera_start();
    }
}

void Userinterface::on_pushButton_4_clicked()
{
    if(num)
    {
    abs->camera_stop();
    ui->label->clear();
    }
}

void Userinterface::on_pushButton_5_clicked()
{
    if(num)
    {
    thread->start();
    }
}

void Userinterface::on_pushButton_6_clicked()
{
    if(num)
    {
    thread->stopping();
    thread->wait();
    ui->label_2->clear();

    }
}

void Userinterface::on_pushButton_7_clicked()
{
    if(num)
    {
    if (sche) { // 直接使用外部传递的实例
        sche->show();
    }
    }
}

void Userinterface::on_pushButton_message_clicked()
{
    if (!msg) {
        msg = new myMessage();
        msg->setWindowFlags(Qt::Window | Qt::WindowCloseButtonHint);
        msg->setSocket(client);
        setMyMessage(msg); // 保存消息窗口指针
    }

    msg->show();
    msg->activateWindow();
}
void Userinterface::on_pushButton_8_clicked()
{
    QString mytext = ui->lineEdit->text();

    Pack pack;
    pack.setType(TYPE_TEXT);

    // 在自己的聊天窗口显示发送的消息
    QString targetUser = "all";

    pack << currentUsername << targetUser << mytext ;
        // 发送消息
    pack >> client;
    QString text=QString("%1: %2").arg(currentUsername).arg(mytext);
    ui->textEdit->append(text);
    // 清空输入框
    ui->lineEdit->clear();
}
void Userinterface::textshow(QString currentUsername,QString text){
    QString mytext=QString("%1: %2").arg(currentUsername).arg(text);
    ui->textEdit->append(mytext);
}
void Userinterface::setPic(QPixmap &pic)
{
    pic = pic.scaled(ui->label->size());
    ui->label->setPixmap(pic);
}

void Userinterface::on_pushButton_9_clicked()
{
    // 启动/停止音频采集
    if (audioInput->input->state() != QAudio::ActiveState) {
        audioInput->start();
        qDebug() << "音频采集已启动";

    } else {
        // 停止音频采集
        audioInput->input->stop();
        qDebug() << "音频采集已停止";

    }

}

void Userinterface::handleAudioData(const QByteArray& audioData)
{
    // 处理音频数据 - 可以选择发送到服务器或本地播放

    // 方式1: 通过网络发送音频数据到服务器（采用分片发送机制）
    if(client && client->state() == QTcpSocket::ConnectedState) {
        Pack pack;
        int audio_size = audioData.size(); // 音频数据总大小
        int writed_size = 0; // 记录已发送多少字节

        while(1) {
            if(writed_size + 4096 >= audio_size) {
                // 如果在当前已发送音频字节数的基础上，再发送4096字节，超出音频总大小，说明本次发送是音频的最后一包
                pack.setType(TYPE_SEND_AUDIO_END);
                pack.append(audioData.data() + writed_size, audio_size - writed_size);
                pack >> client;
                break;
            } else {
                // 音频的前面几包
                pack.setType(TYPE_SENDING_AUDIO);
                pack.append(audioData.data() + writed_size, 4096);
                pack >> client;
            }
            writed_size += 4096;
        }
        qDebug() << "音频数据已分片发送到服务器，总大小:" << audioData.size() << "字节";
    }

    // 注释掉本地播放避免回音问题
    // 如果需要本地测试，可以取消注释下面的代码

     audioOutput->outPutVoice(audioData);

    qDebug() << "处理音频数据，大小:" << audioData.size() << "字节";
}






